package org.docx4j.openpackaging.parts.relationships;
import java.io.ByteArrayOutputStream;
import java.io.File;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import junit.framework.Assert;
import org.docx4j.convert.out.flatOpcXml.FlatOpcXmlCreator;
import org.docx4j.jaxb.Context;
import org.docx4j.jaxb.NamespacePrefixMapperUtils;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.relationships.AlteredParts.Alterations;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class PatcherTest {
protected static Logger log = LoggerFactory.getLogger(PatcherTest.class);
private static String resourceDir = System.getProperty("user.dir") + "/src/test/resources/AlteredParts/";
static boolean save = true; // so we can check that Word can actually open the result
static String DIR_OUT = System.getProperty("user.dir") + "/src/test/";
/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception {
}
/**
* @throws java.lang.Exception
*/
@After
public void tearDown() throws Exception {
}
@Test
public void initJaxbContext() throws Exception {
// Do this first, so it is not included
// in timing of first test.
Context.getWmlObjectFactory();
}
@Test
public void testSimpleDocx() throws Exception {
// Should return no differences
log.warn("\ntestSimpleDocx\n");
String inputfilepath = resourceDir + "paragraph-single.docx";
WordprocessingMLPackage thisPackage = WordprocessingMLPackage.load(new java.io.File(inputfilepath));
WordprocessingMLPackage otherPackage = WordprocessingMLPackage.load(new java.io.File(inputfilepath));
Alterations alterations = AlteredParts.start(thisPackage, otherPackage);
Patcher.apply(otherPackage, alterations);
// if (save) {
// SaveToZipFile saver = new SaveToZipFile(otherPackage);
// saver.save(DIR_OUT+"patch-producing-header-section2.docx");
// }
Assert.assertTrue(java.util.Arrays.equals(
marshallFlatOPC(thisPackage).toByteArray(),
marshallFlatOPC(otherPackage).toByteArray() ));
}
@Test
public void testExtraParagraph() throws Exception {
// Only document.xml should be different
log.warn("\ntestExtraParagraph\n");
WordprocessingMLPackage thisPackage = WordprocessingMLPackage.load(
new java.io.File(resourceDir + "paragraph-single.docx"));
WordprocessingMLPackage otherPackage = WordprocessingMLPackage.load(
new java.io.File(resourceDir + "paragraph-two.docx"));
Alterations alterations = AlteredParts.start(thisPackage, otherPackage);
Patcher.apply(otherPackage, alterations);
// if (save) {
// SaveToZipFile saver = new SaveToZipFile(otherPackage);
// saver.save(DIR_OUT+"patch-producing-header-section2.docx");
// }
Assert.assertTrue(java.util.Arrays.equals(
marshallFlatOPC(thisPackage).toByteArray(),
marshallFlatOPC(otherPackage).toByteArray() ));
}
@Test
public void testHyperlink() throws Exception {
// document.xml and rels should be different,
// and styles, since hyperlink style is now in use
log.warn("\ntestHyperlink\n");
WordprocessingMLPackage thisPackage = WordprocessingMLPackage.load(
new java.io.File(resourceDir + "hyperlink.docx"));
WordprocessingMLPackage otherPackage = WordprocessingMLPackage.load(
new java.io.File(resourceDir + "paragraph-single.docx"));
Alterations alterations = AlteredParts.start(thisPackage, otherPackage);
alterations.debug();
Patcher.apply(otherPackage, alterations);
// if (save) {
// SaveToZipFile saver = new SaveToZipFile(otherPackage);
// saver.save(DIR_OUT+"patch-producing-header-section2.docx");
// }
byte[] array1 = marshallFlatOPC(thisPackage).toByteArray();
byte[] array2 = marshallFlatOPC(otherPackage).toByteArray();
Assert.assertTrue(java.util.Arrays.equals(
array1,
array2));
}
@Test
public void testImageScaled() throws Exception {
// document.xml should be different,
log.warn("\ntestImageScaled\n");
WordprocessingMLPackage thisPackage = WordprocessingMLPackage.load(
new java.io.File(resourceDir + "image-png1.docx"));
WordprocessingMLPackage otherPackage = WordprocessingMLPackage.load(
new java.io.File(resourceDir + "image-png1-scaled.docx"));
Alterations alterations = AlteredParts.start(thisPackage, otherPackage);
Patcher.apply(otherPackage, alterations);
// if (save) {
// SaveToZipFile saver = new SaveToZipFile(otherPackage);
// saver.save(DIR_OUT+"patch-producing-header-section2.docx");
// }
Assert.assertTrue(java.util.Arrays.equals(
marshallFlatOPC(thisPackage).toByteArray(),
marshallFlatOPC(otherPackage).toByteArray() ));
}
@Test
public void testImagesDifferentPng() throws Exception {
// document.xml and image part should be different,
// but rels unchanged
log.warn("\testImagesDifferentPng\n");
WordprocessingMLPackage thisPackage = WordprocessingMLPackage.load(
new java.io.File(resourceDir + "image-png1.docx"));
WordprocessingMLPackage otherPackage = WordprocessingMLPackage.load(
new java.io.File(resourceDir + "image-png2.docx"));
Alterations alterations = AlteredParts.start(thisPackage, otherPackage);
Patcher.apply(otherPackage, alterations);
// if (save) {
// SaveToZipFile saver = new SaveToZipFile(otherPackage);
// saver.save(DIR_OUT+"patch-producing-header-section2.docx");
// }
Assert.assertTrue(java.util.Arrays.equals(
marshallFlatOPC(thisPackage).toByteArray(),
marshallFlatOPC(otherPackage).toByteArray() ));
}
@Test
public void testImagesRelId() throws Exception {
// a jpg inserted before, so the png's relId is now different
// document.xml and rels should be different,
// and extra image reported
// Because we currently match images on name only, and
// png is now called image2.png, that has changed as well.
log.warn("\ntestImagesDifferentPng\n");
WordprocessingMLPackage thisPackage = WordprocessingMLPackage.load(
new java.io.File(resourceDir + "images-jpg then png2.docx"));
WordprocessingMLPackage otherPackage = WordprocessingMLPackage.load(
new java.io.File(resourceDir + "image-png2.docx"));
Alterations alterations = AlteredParts.start(thisPackage, otherPackage);
Patcher.apply(otherPackage, alterations);
// if (save) {
// SaveToZipFile saver = new SaveToZipFile(otherPackage);
// saver.save(DIR_OUT+"patch-producing-header-section2.docx");
// }
Assert.assertTrue(java.util.Arrays.equals(
marshallFlatOPC(thisPackage).toByteArray(),
marshallFlatOPC(otherPackage).toByteArray() ));
}
@Test
public void testImagesOrderSwapped() throws Exception {
// document.xml and rels should be different;
// Because we currently match images on name only,
// both image names have changed as well.
log.warn("\ntestImagesOrderSwapped\n");
WordprocessingMLPackage thisPackage = WordprocessingMLPackage.load(
new java.io.File(resourceDir + "images-jpg then png2.docx"));
WordprocessingMLPackage otherPackage = WordprocessingMLPackage.load(
new java.io.File(resourceDir + "images-png2 then jpg.docx"));
Alterations alterations = AlteredParts.start(thisPackage, otherPackage);
Patcher.apply(otherPackage, alterations);
// if (save) {
// SaveToZipFile saver = new SaveToZipFile(otherPackage);
// saver.save(DIR_OUT+"patch-producing-header-section2.docx");
// }
Assert.assertTrue(java.util.Arrays.equals(
marshallFlatOPC(thisPackage).toByteArray(),
marshallFlatOPC(otherPackage).toByteArray() ));
}
@Test
public void testHeaderAdded() throws Exception {
// document.xml and rels should be different,
// and headers added: Word adds 3 x headers, 3 x footers, endnotes, and footnotes
// plus header style
log.warn("\ntestHeaderAdded\n");
WordprocessingMLPackage thisPackage = WordprocessingMLPackage.load(
new java.io.File(resourceDir + "header-simple.docx"));
WordprocessingMLPackage otherPackage = WordprocessingMLPackage.load(
new java.io.File(resourceDir + "paragraph-single.docx"));
Alterations alterations = AlteredParts.start(thisPackage, otherPackage);
Patcher.apply(otherPackage, alterations);
// if (save) {
// SaveToZipFile saver = new SaveToZipFile(otherPackage);
// saver.save(DIR_OUT+"patch-producing-header-section2.docx");
// }
Assert.assertTrue(java.util.Arrays.equals(
marshallFlatOPC(thisPackage).toByteArray(),
marshallFlatOPC(otherPackage).toByteArray() ));
}
@Test
public void testHeaderAddedSection2() throws Exception {
// document.xml and rels should be different,
// and headers added: doc now contains 2 x headers, 0 x footers, endnotes, and footnotes
// Interesting that the number of header parts is reduced (and content of header1.xml changed)
log.warn("\ntestHeaderAddedSection2\n");
WordprocessingMLPackage thisPackage = WordprocessingMLPackage.load(
new java.io.File(resourceDir + "header-section2.docx"));
WordprocessingMLPackage otherPackage = WordprocessingMLPackage.load(
new java.io.File(resourceDir + "header-simple.docx"));
Alterations alterations = AlteredParts.start(thisPackage, otherPackage);
Patcher.apply(otherPackage, alterations);
// if (save) {
// SaveToZipFile saver = new SaveToZipFile(otherPackage);
// saver.save(DIR_OUT+"patch-producing-header-section2.docx");
// }
Assert.assertTrue(java.util.Arrays.equals(
marshallFlatOPC(thisPackage).toByteArray(),
marshallFlatOPC(otherPackage).toByteArray() ));
}
@Test
public void testHeaderImageAdded() throws Exception {
// the affected header should be different,
// plus image + header rels
log.warn("\ntestHeaderImageAdded\n");
WordprocessingMLPackage thisPackage = WordprocessingMLPackage.load(
new java.io.File(resourceDir + "header-simple-plus-image.docx"));
WordprocessingMLPackage otherPackage = WordprocessingMLPackage.load(
new java.io.File(resourceDir + "header-simple.docx"));
Alterations alterations = AlteredParts.start(thisPackage, otherPackage);
Patcher.apply(otherPackage, alterations);
// if (save) {
// SaveToZipFile saver = new SaveToZipFile(otherPackage);
// saver.save(DIR_OUT+"patch-producing-header-section2.docx");
// }
Assert.assertTrue(java.util.Arrays.equals(
marshallFlatOPC(thisPackage).toByteArray(),
marshallFlatOPC(otherPackage).toByteArray() ));
}
@Test
public void testComment() throws Exception {
// document.xml + rels + added comments part should be different,
// also styles
log.warn("\ntestComment\n");
WordprocessingMLPackage thisPackage = WordprocessingMLPackage.load(
new java.io.File(resourceDir + "comments-one.docx"));
WordprocessingMLPackage otherPackage = WordprocessingMLPackage.load(
new java.io.File(resourceDir + "paragraph-single.docx"));
Alterations alterations = AlteredParts.start(thisPackage, otherPackage);
Patcher.apply(otherPackage, alterations);
// if (save) {
// SaveToZipFile saver = new SaveToZipFile(otherPackage);
// saver.save(DIR_OUT+"patch-producing-header-section2.docx");
// }
Assert.assertTrue(java.util.Arrays.equals(
marshallFlatOPC(thisPackage).toByteArray(),
marshallFlatOPC(otherPackage).toByteArray() ));
}
@Test
public void testComment2() throws Exception {
// document.xml + comments part should be different
log.warn("\ntestComment2\n");
WordprocessingMLPackage thisPackage = WordprocessingMLPackage.load(
new java.io.File(resourceDir + "comments-two.docx"));
WordprocessingMLPackage otherPackage = WordprocessingMLPackage.load(
new java.io.File(resourceDir + "comments-one.docx"));
Alterations alterations = AlteredParts.start(thisPackage, otherPackage);
Patcher.apply(otherPackage, alterations);
// if (save) {
// SaveToZipFile saver = new SaveToZipFile(otherPackage);
// saver.save(DIR_OUT+"patch-producing-header-section2.docx");
// }
Assert.assertTrue(java.util.Arrays.equals(
marshallFlatOPC(thisPackage).toByteArray(),
marshallFlatOPC(otherPackage).toByteArray() ));
}
private ByteArrayOutputStream marshallFlatOPC(WordprocessingMLPackage wmlPkg) throws JAXBException, Docx4JException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// Create a org.docx4j.wml.Package object
FlatOpcXmlCreator worker = new FlatOpcXmlCreator(wmlPkg);
org.docx4j.xmlPackage.Package pkg = worker.get();
// Now marshall it
JAXBContext jc = Context.jcXmlPackage;
Marshaller marshaller=jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
NamespacePrefixMapperUtils.setProperty(marshaller,
NamespacePrefixMapperUtils.getPrefixMapper());
marshaller.marshal(pkg, baos);
// marshaller.marshal(pkg, System.out);
return baos;
}
}